﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;

namespace DogJson
{
    public enum JsonValueType : byte
    {
        None = 0,
        String = 1,
        Long = 2,
        Double = 3,
        Boolean = 4,
        Object = 5, 
        Array = 6,
    }
    public unsafe class JsonRender
    {
        static double[] pow309 = new double[309];
        static double[] pow309negative = new double[309];
        private static bool initializedPow = false;


        private static object mutex = new object();
        private static bool initialized = false;
        private static JsonRender _ins = null;

        public static JsonRender Instance
        {
            get
            {
                if (!initialized)
                {
                    lock (mutex)
                    {
                        if (_ins == null)
                        {
                            _ins = new JsonRender();
                            initialized = true;
                        }
                    }
                }
                return _ins;
            }
        }

        public unsafe JsonRender(int jsonStackLength = 1024, int poolLength = 65536)
        {
            if (!initializedPow)
            {
                lock (pow309)
                {
                    lock (pow309negative)
                    {
                        for (int i = 0; i < 309; i++)
                        {
                            pow309[i] = Math.Pow(10, i);
                            pow309negative[i] = Math.Pow(10, -i);
                        }
                        initializedPow = true;
                    }
                }
            }

            this.jsonStackLength = jsonStackLength;
            this.poolLength = poolLength;


            stackIntPtr = Marshal.AllocHGlobal(jsonStackLength * Marshal.SizeOf(typeof(JsonValue*)));
            objectQueueIntPtr = Marshal.AllocHGlobal(poolLength * Marshal.SizeOf(typeof(JsonObject)));
            poolIntPtr = Marshal.AllocHGlobal(poolLength * Marshal.SizeOf(typeof(JsonValue)));

            //pool = (JsonValue*)poolIntPtr.ToPointer();
            pool = new JsonValue[poolLength];
            objectQueue = new JsonObject[poolLength];
            stack = new int[jsonStackLength];


            //pool = (JsonValue*)poolIntPtr.ToPointer();
            //jsonStack = (JsonValue**)jsonStackIntPtr.ToPointer();
            //jsonStackHead = jsonStack[0];


            fixed (char* vs = "true")
            {
                truelong = *(long*)vs;
            }
            fixed (char* vs = "fals")
            {
                falslong = *(long*)vs;
            }
            fixed (char* vs = "null")
            {
                nulllong = *(long*)vs;
            }
            fixed (char* vs = "alse")
            {
                alselong = *(long*)vs;
            }
        }

        long truelong;
        long falslong;
        long nulllong;
        long alselong;

        IntPtr stackIntPtr;
        IntPtr poolIntPtr;
        IntPtr objectQueueIntPtr;

        //[StructLayout(LayoutKind.Explicit)]
        public struct JsonObject
        {
            //[FieldOffset(0)]
            public int keyStringStart;
            public int keyStringLength;

            public int objectQueueIndex;

            public int parentObjectIndex;

            public bool isObject;

            public int arrayCount;

            public int arrayIndex;
        }
        

        public class CreateObjectItem
        {
            public CreateObjectItem(int index) {
                this.index = index;
            }
            public object obj;
            public Type type;
            public FieldInfo fieldInfo;

            public Array objArray;
            public TypeCode ArrayItemTypeCode;
            public Type ArrayItemType;
            public int ArrayRank;
            public int[] ArrayRankLengths;


            public List<CreateObjectItem> sub = new List<CreateObjectItem>();
            public bool isValueType;
            public int index;
            public CollectionArrayBase collection; 
        }


        int keyStringStart = 0;
        int keyStringLength = 0;
        int vStringStart = 0;
        int vStringLength = 0;

        JsonObject[] objectQueue;
        JsonValue[] pool;
        int[] stack;


        int jsonStackLength = 1024;
        int poolLength = 65536;

        int stackIndex = 0;
        int poolIndex = 0;
        int objectQueueIndex = 0;

        unsafe string Debug(string str, int index, string txt)
        {
            int line = 1;
            int length = str.Length;
            fixed (char* vs = str)
            {
                char* now = vs;
                for (int i = 0; i < index; i++)
                {
                    if (*now == '\n')
                    {
                        ++line;
                    }
                    ++now;
                }
            }
            txt += " 第" + line + "行";
            return txt;
        }

        public unsafe int ReadJsonText(string str)
        {
            int length = str.Length;
            fixed (char* vs = str)
            {
                char* now = vs;
                int objectAnalysisNowIndex = 0;

                stackIndex = 0;
                poolIndex = 0;
                keyStringLength = 0;
                keyStringStart = 0;
                objectQueueIndex = 0;

                double v_double = 0;
                double v_decimal = 1;
                long v_long = 0;
                JsonValue json_value;
                bool fu = false;
                int i = 0;
                //先读初始状态 这里 先只支持{开头的数据
                for (; i < length; ++i, ++now)
                {
                    switch (*now)
                    {
                        case '{':
                            objectQueue[objectQueueIndex].objectQueueIndex = objectQueueIndex;
                            objectQueue[objectQueueIndex].parentObjectIndex = -1;
                            objectQueue[objectQueueIndex].keyStringStart = 0;
                            objectQueue[objectQueueIndex].keyStringLength = 1;
                            objectQueue[objectQueueIndex].isObject = true;

                            stack[stackIndex] = objectQueueIndex;
                            ++objectQueueIndex;
                            goto Run;
                        case ' ':
                        case '\t':
                        case '\r':
                        case '\n':
                            break;

                        case '"':
                        case ':':
                        case '}':
                        case '[':
                        case ']':
                        case ',':
                        default:
                            throw new Exception("错误开头" + *now);
                    }
                }
            Run:

                do
                {
                Loop:
                    if (stackIndex == -1)
                    {
                        break;
                    }
                    if (objectQueue[stack[stackIndex]].isObject)
                    {
                        goto State_Object;
                    }
                    else
                    {
                        goto State_Array;
                    }

                State_Object:
                    //下一个必出" 或}
                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)
                        {
                            case '"':
                                keyStringStart = i + 1;
                                //再找" 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        keyStringLength = i - keyStringStart;
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now == ':')
                                            {
                                                goto Run1;
                                            }
                                        }
                                        throw new Exception("key后面需要:");
                                    }
                                }
                                throw new Exception("字符串未结束 ");
                            case '}':

                                //出栈 
                                --stackIndex;
                                if (stackIndex == -1)
                                {
                                    goto BACK;
                                }
                                if (objectQueue[stack[stackIndex]].isObject)
                                {
                                    goto State_Object;
                                }
                                else
                                {
                                    objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                    ++objectQueue[stack[stackIndex]].arrayCount;
                                    goto State_Array;
                                }

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                            case ',':
                                break;
                            default:
                                throw new Exception(Debug(str, i, "对象 下面只能有keyvalue结构 " + *now));
                        }
                    }
                Run1:
                    //key:后面只能是 布尔、数值、对象 、数组 再找下 " { [ 其他  不能是 } : , ]  

                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)
                        {
                            case '"':
                                vStringStart = i + 1;

                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        vStringLength = i - vStringStart;
                                        goto Run2;
                                    }
                                }
                                throw new Exception("字符串未结束 ");
                            Run2:
                                // 下必 ,} 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    switch (*now)
                                    {
                                        case '}':
                                            //string入队
                                            //json_value = &pool[poolIndex++];
                                            pool[poolIndex].type = JsonValueType.String;
                                            pool[poolIndex].keyStringLength = keyStringLength;
                                            pool[poolIndex].keyStringStart = keyStringStart;
                                            pool[poolIndex].vStringStart = vStringStart;
                                            pool[poolIndex].vStringLength = vStringLength;
                                            pool[poolIndex].objectQueueIndex = stack[stackIndex];
                                            ++poolIndex;
                                            Console.WriteLine(new string(vs, keyStringStart, keyStringLength));

                                            //objectNext 赋值
                                            //(*jsonStackNow)->objectIndex = poolIndex;
                                            //出栈 
                                            --stackIndex;

                                            if (stackIndex == -1)
                                            {
                                                goto BACK;
                                            }
                                            if (objectQueue[stack[stackIndex]].isObject)
                                            {
                                                goto State_Object;
                                            }
                                            else
                                            {
                                                objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                goto State_Array;
                                            }
                                            //goto Loop;
                                        case ',':
                                            //string入队
                                            //json_value = &pool[poolIndex++];
                                            pool[poolIndex].type = JsonValueType.String;
                                            pool[poolIndex].keyStringLength = keyStringLength;
                                            pool[poolIndex].keyStringStart = keyStringStart;
                                            pool[poolIndex].vStringStart = vStringStart;
                                            pool[poolIndex].vStringLength = vStringLength;
                                            pool[poolIndex].objectQueueIndex = stack[stackIndex];
                                            ++poolIndex;

                                            goto State_Object;
                                        case ' ':
                                        case '\t':
                                        case '\r':
                                        case '\n':
                                            break;
                                        default:
                                            throw new Exception("key:value后面只能是,或者}");
                                    }
                                }
                                throw new Exception("key:value后面必须要跟,或者} 未正常 结尾");

                            case '{':
                                //新建object赋予string名字 object入栈

                                objectQueue[objectQueueIndex].objectQueueIndex = objectQueueIndex;
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].keyStringStart = keyStringStart;
                                objectQueue[objectQueueIndex].keyStringLength = keyStringLength;
                                Console.WriteLine(new string(vs, keyStringStart, keyStringLength));
                                objectQueue[objectQueueIndex].isObject = true;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Object;

                            case '[':

                                //新建array赋予string名字 array入栈
                                objectQueue[objectQueueIndex].objectQueueIndex = objectQueueIndex;
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].keyStringStart = keyStringStart;
                                objectQueue[objectQueueIndex].keyStringLength = keyStringLength;
                                objectQueue[objectQueueIndex].isObject = false;
                                objectQueue[objectQueueIndex].arrayCount = 0;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Array;


                            case 't':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == truelong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = true;
                                        now += 4;
                                        i += 4;
                                        goto Value;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            case 'n':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == nulllong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.None;
                                        now += 4;
                                        i += 4;
                                        goto Value;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            case 'f':
                                if (i < length + 4)
                                {
                                    ++now;
                                    ++i;
                                    long nameLong = *(long*)(now);
                                    if (nameLong == alselong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = false;
                                        now += 4;
                                        i += 4;
                                        goto Value;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            default:
                                fu = false;
                                if (*now < '0' || *now > '9')
                                {
                                    if (*now == '-')
                                    {
                                        fu = true;
                                        //负号后面可以加空格
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now != ' ')
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else if (*now == '+')
                                    {
                                        ++i; ++now;
                                    }
                                    else
                                    {
                                        throw new Exception("key:value后面必须要跟,或者}" + *now);
                                    }
                                }
                                json_value = pool[poolIndex++];
                                v_long = (*now - '0');
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == '.')
                                        {
                                            goto Dot;
                                        }
                                        else
                                        {
                                            json_value.type = JsonValueType.Long;
                                            json_value.valueLong = fu ? -v_long : v_long;
                                            goto Value;
                                        }
                                    }
                                    else
                                    {
                                        v_long *= 10;
                                        v_long += (*now - '0');
                                    }
                                }
                                //long
                                throw new Exception("key:value后面必须要跟,或者}" + *now);

                            Dot:
                                v_double = v_long;
                                //点
                                v_decimal = 0.1;
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == 'E' || *now == 'e')
                                        {
                                            ++now; ++i;
                                            if (*now == '-')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309negative[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value;
                                            }
                                            else if (*now == '+')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value;
                                            }

                                        }
                                        break;
                                    }
                                    else
                                    {
                                        v_double += (*now - '0') * v_decimal;
                                        v_decimal *= 0.1;
                                    }
                                }
                                json_value.type = JsonValueType.Double;
                                json_value.valueDouble = fu ? -v_double : v_double;
                            //goto Value;
                            //throw new Exception("key:后面的value解析错误");

                            Value:

                                for (; i < length; ++i, ++now)
                                {
                                    switch (*now)
                                    {
                                        case ' ':
                                        case '\t':
                                        case '\r':
                                        case '\n':
                                            break;

                                        case ',':
                                            json_value.keyStringLength = keyStringLength;
                                            json_value.keyStringStart = keyStringStart;
                                            json_value.objectQueueIndex = stack[stackIndex];
                                            pool[poolIndex - 1] = json_value;
                                            Console.WriteLine(new string(vs, keyStringStart, keyStringLength));

                                            goto State_Object;
                                        case '}':

                                            json_value.keyStringLength = keyStringLength;
                                            json_value.keyStringStart = keyStringStart;
                                            json_value.objectQueueIndex = stack[stackIndex];
                                            pool[poolIndex - 1] = json_value;
                                            Console.WriteLine(new string(vs, keyStringStart, keyStringLength));

                                            //objectNext 赋值
                                            //(*jsonStackNow)->objectIndex = poolIndex;
                                            //出栈 
                                            --stackIndex;

                                            if (stackIndex == -1)
                                            {
                                                goto BACK;
                                            }
                                            if (objectQueue[stack[stackIndex]].isObject)
                                            {
                                                goto State_Object;
                                            }
                                            else
                                            {
                                                objectQueue[stack[stackIndex + 1]].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                goto State_Array;
                                            }
                                        //goto Loop;
                                        default:
                                            throw new Exception("key:value后面必须要跟,或者} ,");
                                    }
                                }
                                throw new Exception("key:value后面必须要跟,或者} ,未正常结尾");

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                                break;

                            case ':':
                            case '}':
                            case ',':
                            case ']':
                                throw new Exception("key:后面不能是" + *now);
                        }
                    }
                //}
                ////else
                //{

                State_Array:
                    //" ]
                    for (++i, ++now; i < length; ++i, ++now)
                    {
                        switch (*now)
                        {
                            case '"':
                                vStringStart = i + 1;
                                //再找" 
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now == '"')
                                    {
                                        vStringLength = i - vStringStart;
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            //必出 , ]
                                            if (*now == ',')
                                            {
                                                json_value = pool[poolIndex++];
                                                json_value.type = JsonValueType.String;
                                                json_value.vStringStart = vStringStart;
                                                json_value.vStringLength = vStringLength;
                                                json_value.objectQueueIndex = stack[stackIndex];
                                                json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                pool[poolIndex - 1] = json_value;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                goto State_Array;
                                            }
                                            else if (*now == ']')
                                            {
                                                json_value = pool[poolIndex++];
                                                json_value.type = JsonValueType.String;
                                                json_value.vStringStart = vStringStart;
                                                json_value.vStringLength = vStringLength;
                                                json_value.objectQueueIndex = stack[stackIndex];
                                                json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                                pool[poolIndex - 1] = json_value;
                                                ++objectQueue[stack[stackIndex]].arrayCount;
                                                //出栈
                                                --stackIndex;
                                                goto Loop;
                                            }
                                        }
                                        throw new Exception("key后面需要:");
                                    }
                                }
                                throw new Exception("字符串未结束 ");

                            case '{':
                                //数组元素没有Key
                                // { 新建 object 入栈
                                objectQueue[objectQueueIndex].objectQueueIndex = objectQueueIndex;
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].isObject = true;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Object;
                            //goto Loop;

                            case '[':
                                // [新建 array 入栈
                                objectQueue[objectQueueIndex].objectQueueIndex = objectQueueIndex;
                                objectQueue[objectQueueIndex].parentObjectIndex = stack[stackIndex];
                                objectQueue[objectQueueIndex].isObject = false;
                                objectQueue[objectQueueIndex].arrayCount = 0;
                                objectQueue[objectQueueIndex].arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                ++objectQueue[stack[stackIndex]].arrayCount;

                                stack[++stackIndex] = objectQueueIndex;
                                ++objectQueueIndex;

                                goto State_Array;
                            case 't':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == truelong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = true;
                                        now += 4;
                                        i += 4;
                                        goto Value2;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            case 'n':
                                if (i < length + 4)
                                {
                                    long nameLong = *(long*)(now);
                                    if (nameLong == nulllong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.None;
                                        now += 4;
                                        i += 4;
                                        goto Value2;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            case 'f':
                                if (i < length + 4)
                                {
                                    ++now;
                                    ++i;
                                    long nameLong = *(long*)(now);
                                    if (nameLong == alselong)
                                    {
                                        json_value = pool[poolIndex++];
                                        json_value.type = JsonValueType.Boolean;
                                        json_value.valueBool = false;
                                        now += 4;
                                        i += 4;
                                        goto Value2;
                                    }
                                }
                                throw new Exception("key:后面的value解析错误");
                            default:
                                fu = false;
                                if (*now < '0' || *now > '9')
                                {
                                    if (*now == '-')
                                    {
                                        fu = true;
                                        //负号后面可以加空格
                                        for (++i, ++now; i < length; ++i, ++now)
                                        {
                                            if (*now != ' ')
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else if (*now == '+')
                                    {
                                        ++i; ++now;
                                    }
                                    else
                                    {
                                        throw new Exception("key:value后面必须要跟,或者}" + *now);
                                    }
                                }
                                json_value = pool[poolIndex++];
                                v_long = (*now - '0');
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == '.')
                                        {
                                            goto Dot2;
                                        }
                                        else
                                        {
                                            json_value.type = JsonValueType.Long;
                                            json_value.valueLong = fu ? -v_long : v_long;
                                            goto Value2;
                                        }
                                    }
                                    else
                                    {
                                        v_long *= 10;
                                        v_long += (*now - '0');
                                    }
                                }
                                //long
                                throw new Exception("key:value后面必须要跟,或者}" + *now);

                            Dot2:
                                v_double = v_long;
                                //点
                                v_decimal = 0.1;
                                for (++i, ++now; i < length; ++i, ++now)
                                {
                                    if (*now < '0' || *now > '9')
                                    {
                                        if (*now == 'E' || *now == 'e')
                                        {
                                            ++now; ++i;
                                            if (*now == '-')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309negative[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value2;
                                            }
                                            else if (*now == '+')
                                            {
                                                v_long = 0;

                                                for (++i, ++now; i < length; ++i, ++now)
                                                {
                                                    if (*now < '0' || *now > '9')
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        v_long *= 10;
                                                        v_long += (*now - '0');
                                                    }
                                                }
                                                v_double *= pow309[v_long];
                                                json_value.type = JsonValueType.Double;
                                                json_value.valueDouble = fu ? -v_double : v_double;
                                                goto Value2;
                                            }

                                        }
                                        break;
                                    }
                                    else
                                    {
                                        v_double += (*now - '0') * v_decimal;
                                        v_decimal *= 0.1;
                                    }
                                }
                                json_value.type = JsonValueType.Double;
                                json_value.valueDouble = fu ? -v_double : v_double;
                            //goto Value;
                            //throw new Exception("key:后面的value解析错误");

                            Value2:
                                json_value.objectQueueIndex = stack[stackIndex];
                                pool[poolIndex - 1] = json_value;
                                for (; i < length; ++i, ++now)
                                {
                                    switch (*now)
                                    {
                                        case ' ':
                                        case '\t':
                                        case '\r':
                                        case '\n':
                                            break;

                                        case ',':
                                            json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                            ++objectQueue[stack[stackIndex]].arrayCount;
                                            pool[poolIndex - 1] = json_value;
                                            goto State_Array;
                                        case ']':
                                            //出栈 
                                            json_value.arrayIndex = objectQueue[stack[stackIndex]].arrayCount;
                                            ++objectQueue[stack[stackIndex]].arrayCount;
                                            pool[poolIndex - 1] = json_value;
                                            --stackIndex;
                                            goto Loop;
                                        default:
                                throw new Exception(Debug(str, i, "key:value后面必须要跟,或者} , " + *now));
                                    }
                                }
                                throw new Exception("key:value后面必须要跟,或者} ,未正常结尾");

                            case ' ':
                            case '\t':
                            case '\r':
                            case '\n':
                            case ',':
                                break;
                            case ']':
                                //(*jsonStackNow)->objectIndex = poolIndex;
                                //出栈 
                                --stackIndex;
                                goto Loop;

                            case ':':
                            case '}':
                                throw new Exception("key:后面不能是" + *now);
                        }
                    }

                    //}

                    //DBJ
                }
                while (stackIndex >= 0);
                BACK:
                Console.WriteLine();
                //if (stackIndex == -1)
                for (int vvv = 1; vvv < objectQueueIndex; vvv++)
                {
                    Console.WriteLine(

                       vvv + "," +
                        new string(vs, objectQueue[vvv].keyStringStart, objectQueue[vvv].keyStringLength)
                        + "," +
                        new string(vs, objectQueue[objectQueue[vvv].parentObjectIndex].keyStringStart,
                          objectQueue[objectQueue[vvv].parentObjectIndex].keyStringLength)
                     );
                }
                for (int vvv = 0; vvv < poolIndex; vvv++)
                {

                    Console.WriteLine(pool[vvv].objectQueueIndex
                        + "," +
                        new string(vs, pool[vvv].keyStringStart, pool[vvv].keyStringLength)
                        + "," +
                        new string(vs, objectQueue[pool[vvv].objectQueueIndex].keyStringStart,
                        objectQueue[pool[vvv].objectQueueIndex].keyStringLength)
                        );
                }
            }

            //JsonValue[] over = new JsonValue[poolIndex];
            //fixed (JsonValue* vs = &over[0])
            //{
            //    Marshal.ReAllocHGlobal(poolIntPtr, new IntPtr( * sizeof(JsonValue)));
            //    new IntPtr((void*)vs);
            //}
            return poolIndex;

            //return Marshal.GetObjectsForNativeVariants<JsonValue>(poolIntPtr, poolIndex * sizeof(JsonValue));
        }


        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 
        public unsafe object CreateObject(Type type, string str)
        {
            int length = str.Length;
            CreateObjectItem[] createObjectItems = new CreateObjectItem[objectQueueIndex];
            fixed (char* vs = str)
            {
                createObjectItems[0] = new CreateObjectItem(0);
                createObjectItems[0].type = type;
                createObjectItems[0].obj = System.Activator.CreateInstance(type);
                createObjectItems[0].isValueType = type.IsValueType;

                //对象数组创建
                for (int i = 1; i < objectQueueIndex; i++)
                {
                    CreateObjectItem myObject = createObjectItems[i] = new CreateObjectItem(i);
                    JsonObject v = objectQueue[i];
                    JsonObject parent = objectQueue[v.parentObjectIndex];
                    CreateObjectItem parentObject = createObjectItems[v.parentObjectIndex];

                    parentObject.sub.Add(myObject);
                    if (parent.isObject)
                    {
                        string key = new string(vs, v.keyStringStart, v.keyStringLength);
                        var fieldInfo = parentObject.type.GetField(key, bindingFlags);

                        myObject.fieldInfo = fieldInfo;
                        myObject.type = fieldInfo.FieldType;
                    }
                    else
                    {
                        CollectionArrayBase collectionParent = parentObject.collection;
                        if (collectionParent == null)
                        {
                            myObject.type = parentObject.ArrayItemType;
                        }
                        else
                        {
                            myObject.type = collectionParent.ItemType(v.arrayIndex);
                        }
                    }

                    if (v.isObject)
                    {
                        myObject.obj = Activator.CreateInstance(myObject.type);
                    }
                    else
                    {
                        CollectionArrayBase collection;
                        if (CollectionManager.formatterAllMap.TryGetValue(myObject.type, out collection))
                        {
                            myObject.obj = collection.CreateArray(v.arrayCount, myObject.type, parentObject.type);
                            myObject.collection = collection;
                            //goto Continue;
                        }
                        else
                        {
                            if (myObject.type.IsGenericType)
                            {
                                Type collectionType;
                                if (CollectionManager.formatterTypeMap.TryGetValue(myObject.type.GetGenericTypeDefinition(), out collectionType))
                                {
                                    Type type1 = collectionType.MakeGenericType(myObject.type.GetGenericArguments());
                                    CollectionManager.formatterAllMap[myObject.type] = collection
                                        = Activator.CreateInstance(type1) as CollectionArrayBase;

                                    myObject.obj = collection.CreateArray(v.arrayCount, myObject.type, parentObject.type);
                                    myObject.collection = collection;
                                    //goto Continue;
                                }
                                else
                                {
                                   if (myObject.type.IsSubclassOf(typeof(MulticastDelegate)))
                                    {
                                        collection = CollectionManager.formatterAllMap[typeof(MulticastDelegate)];
                                        myObject.obj = collection.CreateArray(v.arrayCount, myObject.type, parentObject.type);
                                        myObject.collection = collection;
                                    }
                                    else
                                    {
                                        //myObject.obj = Activator.CreateInstance(myObject.type);
                                        throw new Exception("JSON数组类型容器未注册");
                                    }
                                }
                            }
                            else
                            {
                                if (myObject.type.IsArray)
                                {
                                    var elementType = myObject.type.GetElementType();
                                    var rank = myObject.type.GetArrayRank();
                                    //var lengths = myObject.type.getl();
                                    //Array array = Array.CreateInstance(elementType, lengths);
                                    if (rank == 1)//数组的秩= 1 直接遍历赋值
                                    {
                                        myObject.ArrayRank = 1;
                                        myObject.ArrayItemType = elementType;
                                        myObject.ArrayItemTypeCode = Type.GetTypeCode(elementType);
                                        myObject.obj = myObject.objArray = Array.CreateInstance(elementType, v.arrayCount);
                                    }
                                    else
                                    {
                                        myObject.ArrayRank = rank;
                                        myObject.ArrayItemType = elementType;
                                        myObject.ArrayItemTypeCode = Type.GetTypeCode(elementType);
                                        myObject.ArrayRankLengths = new int[rank];
                                    }
                                }
                                else
                                {
                                    throw new Exception("类型不是数组");
                                }
                            }
                        }
                    }



                //Continue:
                //    continue;
                }
                object set_value = null;
                //基本类型赋值
                for (int i = 0; i < poolIndex; i++)
                {
                    var v = pool[i];
                    CreateObjectItem myObject = createObjectItems[v.objectQueueIndex];
                    JsonObject parent = objectQueue[v.objectQueueIndex];
                    if (parent.isObject)
                    {
                        string key = new string(vs, v.keyStringStart, v.keyStringLength);
                        //if (key =="str")
                        //{
                        //    int ccc = 0;
                        //}
                        FieldInfo fieldInfo = myObject.type.GetField(key, bindingFlags);
                        var itemTypeCode = Type.GetTypeCode(fieldInfo.FieldType);
                        switch (v.type)
                        {
                            case JsonValueType.String:
                                switch (itemTypeCode)
                                {
                                    case TypeCode.Char:
                                        fieldInfo.SetValue(
                                            myObject.obj, vs[v.vStringStart]);
                                        break;
                                    case TypeCode.String:
                                        fieldInfo.SetValue(
                                            myObject.obj,
                                            new string(vs, v.vStringStart, v.vStringLength));
                                        break;
                                    default:

                                        if (fieldInfo.FieldType.IsEnum)
                                        {
                                            var strEnum = new string(vs, v.vStringStart, v.vStringLength);
                                            Array Arrays = Enum.GetValues(fieldInfo.FieldType);
                                            for (int k = 0; k < Arrays.Length; k++)
                                            {
                                                if (Arrays.GetValue(k).ToString().Equals(strEnum))
                                                {
                                                    fieldInfo.SetValue(
                                                        myObject.obj, Arrays.GetValue(i));
                                                }
                                            }
                                        }
                                        break;
                                }
                                break;
                            case JsonValueType.Long:
                                switch (itemTypeCode)
                                {
                                    case TypeCode.SByte:
                                        fieldInfo.SetValue(
                                            myObject.obj, (SByte)v.valueLong);
                                        break;
                                    case TypeCode.Byte:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Byte)v.valueLong);
                                        break;
                                    case TypeCode.Int16:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Int16)v.valueLong);
                                        break;
                                    case TypeCode.UInt16:
                                        fieldInfo.SetValue(
                                            myObject.obj, (UInt16)v.valueLong);
                                        break;
                                    case TypeCode.Int32:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Int32)v.valueLong);
                                        break;
                                    case TypeCode.UInt32:
                                        fieldInfo.SetValue(
                                            myObject.obj, (UInt32)v.valueLong);
                                        break;
                                    case TypeCode.Int64:
                                        fieldInfo.SetValue(
                                            myObject.obj, v.valueLong);
                                        break;
                                    case TypeCode.UInt64:
                                        fieldInfo.SetValue(
                                            myObject.obj, (UInt64)v.valueLong);
                                        break;
                                    case TypeCode.Single:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Single)v.valueLong);
                                        break;
                                    case TypeCode.Double:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Double)v.valueLong);
                                        break;
                                    case TypeCode.Decimal:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Decimal)v.valueLong);
                                        break;
                                }
                                break;
                            case JsonValueType.Double:
                                switch (itemTypeCode)
                                { 
                                    case TypeCode.Single:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Single)v.valueDouble);
                                        break;
                                    case TypeCode.Double:
                                        fieldInfo.SetValue(
                                            myObject.obj, v.valueDouble);
                                        break;
                                    case TypeCode.Decimal:
                                        fieldInfo.SetValue(
                                            myObject.obj, (Decimal)v.valueDouble);
                                        break;
                                }
                                break;
                            case JsonValueType.Boolean:
                                fieldInfo.SetValue(
                                    myObject.obj, v.valueBool);
                                break;
                            case JsonValueType.Object:
                                if (myObject.type == (typeof(Type)))
                                {
                                    fieldInfo.SetValue(
                                        myObject.obj, Type.GetType(new string(vs, v.vStringStart, v.vStringLength)));
                                }
                                break;
                          default:
                                break;
                        }
                    }
                    else
                    {
                        CollectionArrayBase collection = myObject.collection;
                        if (collection != null)
                        {
                            collection.AddValue(myObject.obj, v.arrayIndex, vs, v);
                        }
                        else
                        {
                            switch (v.type)
                            {
                                case JsonValueType.String:
                                    switch (myObject.ArrayItemTypeCode)
                                    {
                                        case TypeCode.Char:
                                            set_value = vs[v.vStringStart];
                                            break;
                                        case TypeCode.String:
                                            set_value = new string(vs, v.vStringStart, v.vStringLength);
                                            break;
                                        default:
                                            if (myObject.ArrayItemType.IsEnum)
                                            {
                                                var strEnum = new string(vs, v.vStringStart, v.vStringLength);
                                                Array Arrays = Enum.GetValues(myObject.ArrayItemType);
                                                for (int k = 0; k < Arrays.Length; k++)
                                                {
                                                    if (Arrays.GetValue(k).ToString().Equals(strEnum))
                                                    {
                                                        set_value = Arrays.GetValue(i);
                                                    }
                                                }
                                            }
                                            break;
                                    }
                                    break;
                                case JsonValueType.Long:
                                    switch (myObject.ArrayItemTypeCode)
                                    {
                                        case TypeCode.SByte:
                                            set_value = (SByte)v.valueLong;
                                            break;
                                        case TypeCode.Byte:
                                            set_value = (Byte)v.valueLong;
                                            break;
                                        case TypeCode.Int16:
                                            set_value = (Int16)v.valueLong;
                                            break;
                                        case TypeCode.UInt16:
                                            set_value = (UInt16)v.valueLong;
                                            break;
                                        case TypeCode.Int32:
                                            set_value = (Int32)v.valueLong;
                                            break;
                                        case TypeCode.UInt32:
                                            set_value = (UInt32)v.valueLong;
                                            break;
                                        case TypeCode.Int64:
                                            set_value = v.valueLong;
                                            break;
                                        case TypeCode.UInt64:
                                            set_value = (UInt64)v.valueLong;
                                            break;
                                        case TypeCode.Single:
                                            set_value = (Single)v.valueLong;
                                            break;
                                        case TypeCode.Double:
                                            set_value = (Double)v.valueLong;
                                            break;
                                        case TypeCode.Decimal:
                                            set_value = (Decimal)v.valueLong;
                                            break;
                                    }
                                    break;
                                case JsonValueType.Double:
                                    switch (myObject.ArrayItemTypeCode)
                                    {
                                        case TypeCode.Single:
                                            set_value = (Single)v.valueDouble;
                                            break;
                                        case TypeCode.Double:
                                            set_value = (Double)v.valueDouble;
                                            break;
                                        case TypeCode.Decimal:
                                            set_value = (Decimal)v.valueDouble;
                                            break;
                                    }
                                    break;
                                case JsonValueType.Boolean:
                                    set_value = v.valueBool;
                                    break;
                                case JsonValueType.Object:
                                    if (myObject.type == (typeof(Type)))
                                    {
                                        set_value = Type.GetType(new string(vs, v.vStringStart, v.vStringLength));
                                    }
                                    break;
                            }
                            myObject.objArray.SetValue(set_value, v.arrayIndex);
                        }

                     

                    }
                }


                //类类型赋值

                for (int i = createObjectItems.Length - 2; i >= 0; i--)
                {
                    CreateObjectItem parentObject = createObjectItems[i];
                    JsonObject parent = objectQueue[parentObject.index];
                    foreach (var myObject in createObjectItems[i].sub)
                    {
                        JsonObject v = objectQueue[myObject.index];
                        CollectionArrayBase collection = myObject.collection;

                        if (collection != null)
                        {
                            myObject.obj = collection.End(myObject.obj);
                        }
                        CollectionArrayBase parentCollection = parentObject.collection;
                        if (parentCollection == null)
                        {
                            if (parent.isObject)
                            {
                                myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                            }
                            else
                            {

                                parentObject.objArray.SetValue(myObject.obj, v.arrayIndex);
                            }
                        }
                        else
                        {
                            if (parent.isObject)
                            {
                                myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                            }
                            else
                            {
                                parentCollection.Add(parentObject.obj, v.arrayIndex, myObject.obj);
                            }
                        }
                    }


                }

                //for (int i = 0; i < arrayCreateObjectItemsIndex; i++)
                //{
                //    JsonObject v = objectQueue[arrayCreateObjectItems[i]];
                //    JsonObject parent = objectQueue[v.parentObjectIndex];
                //    CreateObjectItem parentObject = createObjectItems[v.parentObjectIndex];
                //    CreateObjectItem myObject = createObjectItems[v.objectQueueIndex];

                //    CollectionArrayBase collection = myObject.collection;
                //    if (collection != null)
                //    {
                //        myObject.obj = collection.End(myObject.obj);
                //    }

                //    CollectionArrayBase parentCollection = parentObject.collection;

                //    if (parentCollection == null)
                //    {
                //        if (parent.isObject)
                //        {
                //            myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                //        }
                //        else
                //        {
                //            ((IList)(parentObject.obj)).Add(myObject.obj);
                //        }
                //    }
                //    else
                //    {
                //        if (parent.isObject)
                //        {
                //            myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                //        }
                //        else
                //        {
                //            parentCollection.Add(parentObject.obj, v.arrayIndex, myObject.obj);
                //        }
                //    }
                //}


                //for (int i = objectQueueIndex - 1; i > 0; i--)
                //{
                //    JsonObject v = objectQueue[i];
                //    JsonObject parent = objectQueue[v.parentObjectIndex];
                //    CreateObjectItem parentObject = createObjectItems[v.parentObjectIndex];
                //    CreateObjectItem myObject = createObjectItems[v.objectQueueIndex];

                //    CollectionArrayBase collection = myObject.collection;
                //    if (collection != null)
                //    {
                //        myObject.obj = collection.End(myObject.obj);
                //    }

                //    CollectionArrayBase parentCollection = parentObject.collection;
                //    if (parentCollection == null)
                //    {
                //        if (parent.isObject)
                //        {
                //            myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                //        }
                //        else
                //        {
                //            ((IList)(parentObject.obj)).Add(myObject.obj);
                //        }
                //    }
                //    else
                //    {
                //        if (parent.isObject)
                //        {
                //            myObject.fieldInfo.SetValue(parentObject.obj, myObject.obj);
                //        }
                //        else
                //        {
                //            parentCollection.Add(parentObject.obj, v.arrayIndex, myObject.obj);
                //        }
                //    }

                //}



                

            
            }




            Console.ReadKey();
            return createObjectItems[0].obj;     
        }


    }
}
